package com.wzy.oa_sys.service.impl.schedule;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wzy.oa_sys.mapper.notice.NoticeMapper;
import com.wzy.oa_sys.mapper.schedule.BoardroomMapper;
import com.wzy.oa_sys.mapper.schedule.ScheduleMapper;
import com.wzy.oa_sys.mapper.schedule.UseBoardroomMapper;
import com.wzy.oa_sys.mapper.user.DeptMapper;
import com.wzy.oa_sys.mapper.user.UserMapper;
import com.wzy.oa_sys.model.pojo.notice.OaNotice;
import com.wzy.oa_sys.model.pojo.schedule.OaBoardroom;
import com.wzy.oa_sys.model.pojo.schedule.OaSchedule;
import com.wzy.oa_sys.model.pojo.schedule.OaUseBoardroom;
import com.wzy.oa_sys.model.pojo.user.OaUser;
import com.wzy.oa_sys.model.request.notice.NoticeReq;
import com.wzy.oa_sys.model.request.schedule.ScheduleReq;
import com.wzy.oa_sys.model.response.schedule.ScheduleResp;
import com.wzy.oa_sys.service.notice.NoticeService;
import com.wzy.oa_sys.service.schedule.ScheduleService;
import com.wzy.oa_sys.util.JwtUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class ScheduleServiceImpl extends ServiceImpl<ScheduleMapper, OaSchedule> implements ScheduleService {

    @Autowired
    private ScheduleMapper scheduleMapper;

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private DeptMapper deptMapper;
    @Autowired
    private BoardroomMapper boardroomMapper;
    @Autowired
    private UseBoardroomMapper useBoardroomMapper;
    @Autowired
    private NoticeService noticeService;
    @Autowired
    private JwtUtil jwtUtil;
    @Autowired
    private NoticeMapper noticeMapper;

    @Override
    public List<ScheduleResp> getScheduleList() {
        List<OaSchedule> scheduleList = scheduleMapper.selectList(null);
        List<ScheduleResp> scheduleRespList = new ArrayList<>();
        scheduleList.forEach(schedule -> {
            ScheduleResp build = ScheduleResp.builder()
                    .id(schedule.getNScheId())
                    .type(schedule.getCType())
                    .title(schedule.getCTitle())
                    .desc(schedule.getCDesc())
                    .starttime(schedule.getDtStartTime())
                    .deadline(schedule.getDtDeadline())
                    .promoter(userMapper.selectUserById(schedule.getNUserId()).getCRealName())
                    .promoterId(schedule.getNUserId())
                    .deptId(schedule.getNDeptId())
                    .build();
            if(schedule.getNDeptId()!= 0){
                build.setDeptname(deptMapper.selectDeptById(schedule.getNDeptId()).getCDeptName());
            }
            if(schedule.getCState().equals("1")){
                build.setState("紧急");
            }else if(schedule.getCState().equals("2")){
                build.setState("重要");
            }else if(schedule.getCState().equals("3")){
                build.setState("一般");
            }
            if(schedule.getNBoardroomId()!= 0){
                build.setBoardroom(boardroomMapper.selectBoardroomById(schedule.getNBoardroomId()).getCNo());
            }else{
                build.setBoardroom("无");
            }
            String s = schedule.getCRecipient();
            if (!s.equals("[]")) {
                String[] numbers = s.replaceAll("[\\[\\]\\s]", "").split(",");
                int[] result = Arrays.stream(numbers)
                        .mapToInt(Integer::parseInt)
                        .toArray();
                StringBuilder sb = new StringBuilder();
                for (int receiver : result) {
                    sb.append(userMapper.selectUserById(receiver).getCRealName()).append(",");
                }
                build.setRecipient(sb.toString().substring(0, sb.length() - 1));
            }else{
                build.setRecipient("所有人");
            }
            scheduleRespList.add(build);
        });

        return scheduleRespList;
    }


    @Override
    public List<ScheduleResp> getMyScheduleList(long myId) {
        QueryWrapper<OaUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("n_user_id", myId);
        OaUser oaUser = userMapper.selectOne(queryWrapper);
        List<OaSchedule> scheduleList = scheduleMapper.selectList(null);
        List<ScheduleResp> scheduleRespList = new ArrayList<>();
        scheduleList.forEach(schedule -> {
            //部门id为0表示发所有人，也包括用户自己||部门id等于当前用户的部门id，并且接收人为空，则表示部门下所有人为接收人
            if(schedule.getNDeptId() == 0||
                    (schedule.getNDeptId() == oaUser.getNDeptId()&&schedule.getCRecipient().equals("[]"))){
                ScheduleResp build = ScheduleResp.builder()
                        .id(schedule.getNScheId())
                        .type(schedule.getCType())
                        .title(schedule.getCTitle())
                        .starttime(schedule.getDtStartTime())
                        .deadline(schedule.getDtDeadline())
                        .promoter(userMapper.selectUserById(schedule.getNUserId()).getCRealName())
                        .build();
                if(schedule.getNDeptId()!= 0){
                    build.setDeptname(deptMapper.selectDeptById(schedule.getNDeptId()).getCDeptName());
                }
                if(schedule.getCState().equals("1")){
                    build.setState("紧急");
                }else if(schedule.getCState().equals("2")){
                    build.setState("重要");
                }else if(schedule.getCState().equals("3")){
                    build.setState("一般");
                }
                scheduleRespList.add(build);
            //日程的部门id等于当前用户的部门id并且接收人不为空，当前用户可能为日程的接收人
            }else if(schedule.getNDeptId() == oaUser.getNDeptId()&&!schedule.getCRecipient().equals("[]")){
                String[] numbers = schedule.getCRecipient().replaceAll("[\\[\\]\\s]", "").split(",");
                int[] result = Arrays.stream(numbers)
                        .mapToInt(Integer::parseInt)
                        .toArray();
                //遍历接收人，如果当前用户在接收人中，则添加到返回列表中
                for(int i:result){
                    if(i == myId){
                        ScheduleResp build = ScheduleResp.builder()
                                .id(schedule.getNScheId())
                                .type(schedule.getCType())
                                .title(schedule.getCTitle())
                                .starttime(schedule.getDtStartTime())
                                .deadline(schedule.getDtDeadline())
                                .promoter(userMapper.selectUserById(schedule.getNUserId()).getCRealName())
                                .build();
                        if(schedule.getNDeptId()!= 0){
                            build.setDeptname(deptMapper.selectDeptById(schedule.getNDeptId()).getCDeptName());
                        }
                        if(schedule.getCState().equals("1")){
                            build.setState("紧急");
                        }else if(schedule.getCState().equals("2")){
                            build.setState("重要");
                        }else if(schedule.getCState().equals("3")){
                            build.setState("一般");
                        }
                        scheduleRespList.add(build);
                        break;
                    }
                }
            }

        });
        return scheduleRespList;
    }

    @Override
    public void updateSchedule(ScheduleReq scheduleReq, Long userId) {
        System.out.println("更新日程内容"+scheduleReq);
        QueryWrapper<OaSchedule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("n_sche_id", scheduleReq.getId());
        OaSchedule oaSchedule = scheduleMapper.selectOne(queryWrapper);
        if(oaSchedule!= null){
            boolean updateFlag = false;
            String baseType = oaSchedule.getCType();
            LocalDateTime baseStartTime = oaSchedule.getDtStartTime();
            LocalDateTime baseDeadline = oaSchedule.getDtDeadline();
            if(scheduleReq.getType()!= null){
                oaSchedule.setCType(scheduleReq.getType());
                updateFlag = true;
            }
            if(scheduleReq.getState()!= null&&!scheduleReq.getState().equals("")){
                oaSchedule.setCState(scheduleReq.getState());
                updateFlag = true;
            }
            if(scheduleReq.getTitle()!= null){
                oaSchedule.setCTitle(scheduleReq.getTitle());
                updateFlag = true;
            }
            if(scheduleReq.getDesc()!= null){
                oaSchedule.setCDesc(scheduleReq.getDesc());
                updateFlag = true;
            }
            if(scheduleReq.getStarttime()!= null&&!scheduleReq.getStarttime().equals(baseStartTime)){
                LocalDateTime starttime = scheduleReq.getStarttime();
                oaSchedule.setDtStartTime(starttime.plusHours(8));
                updateFlag = true;
            }
            if(scheduleReq.getDeadline()!= null&&!scheduleReq.getDeadline().equals(baseDeadline)){
                LocalDateTime deadline = scheduleReq.getDeadline();
                oaSchedule.setDtDeadline(deadline.plusHours(8));
                updateFlag = true;
            }
            //在会议室使用表中添加
            if(scheduleReq.getBoardroomId()!= 0){
                OaUseBoardroom oaUseBoardroom = new OaUseBoardroom();
                oaUseBoardroom.setNBoardroomId(scheduleReq.getBoardroomId());
                oaUseBoardroom.setDtStartTime(oaSchedule.getDtStartTime().plusHours(8));
                oaUseBoardroom.setDtDeadline(oaSchedule.getDtDeadline().plusHours(8));
                useBoardroomMapper.insert(oaUseBoardroom);
            }
            if(baseType.equals("会议")&&!scheduleReq.getType().equals("会议")){
                QueryWrapper<OaUseBoardroom> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("dt_start_time", baseStartTime.plusHours(8));
                queryWrapper1.eq("dt_deadline", baseDeadline.plusHours(8));
                useBoardroomMapper.delete(queryWrapper1);
            }else if(baseType.equals("会议")&&scheduleReq.getType().equals("会议")){
                boolean flag = false;
                if(!baseStartTime.plusHours(8).equals(oaSchedule.getDtStartTime())){
                    flag = true;
                }else if(!baseDeadline.plusHours(8).equals(oaSchedule.getDtDeadline())){
                    flag = true;
                }
                if(flag){
                    QueryWrapper<OaUseBoardroom> queryWrapper2 = new QueryWrapper<>();
                    queryWrapper2.eq("dt_start_time", baseStartTime.plusHours(8));
                    queryWrapper2.eq("dt_deadline", baseDeadline.plusHours(8));
                    useBoardroomMapper.delete(queryWrapper2);
                }
            }
            if(scheduleReq.getDeptname()!= 0){
                oaSchedule.setNDeptId(scheduleReq.getDeptname());
                updateFlag = true;
            }
            if(scheduleReq.getReceiverList()!= null){
                oaSchedule.setCRecipient(scheduleReq.getReceiverList().toString());
                updateFlag = true;
            }
            if(scheduleReq.getBoardroomId()!= 0){
                oaSchedule.setNBoardroomId(scheduleReq.getBoardroomId());
                updateFlag = true;
            }
            if(updateFlag){
                scheduleMapper.update(oaSchedule, queryWrapper);
            }
        }

    }

    @Override
    public void reminder(Integer id,HttpServletRequest request) {
        QueryWrapper<OaNotice> noticeQueryWrapper = new QueryWrapper<>();
        noticeQueryWrapper.eq("n_link_id",id);
        List<OaNotice> oaNotices = noticeMapper.selectList(noticeQueryWrapper);
        LocalDateTime now = LocalDateTime.now();

// 过滤出 releaseTime 与当前时间间隔小于10分钟的 OaNotice
        List<OaNotice> filteredNotices = oaNotices.stream()
                .filter(notice -> {
                    LocalDateTime releaseTime = notice.getDtReleaseTime(); // 假设 getReleaseTime() 返回 LocalDateTime
                    return Duration.between(releaseTime, now).toMinutes() < 10; // 计算时间间隔
                })
                .collect(Collectors.toList());
        if(filteredNotices.size()>0){
            throw new RuntimeException("十分钟内已有对应的提醒");
        }
        Long userId = jwtUtil.extractUserId(request);
        QueryWrapper<OaSchedule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("n_sche_id", id);
        OaSchedule oaSchedule = scheduleMapper.selectOne(queryWrapper);
        if(oaSchedule != null){
            NoticeReq noticeReq = new NoticeReq();
            noticeReq.setType("通知");
            noticeReq.setState(1);
            noticeReq.setTitle("日程提醒");
            noticeReq.setDesc("您有一条日程提醒，请注意查看。可点击链接查看具体信息。");
            noticeReq.setReleasetime(LocalDateTime.now().minusHours(8));
            noticeReq.setDeptname(oaSchedule.getNDeptId());
            String cRecipient = oaSchedule.getCRecipient();
            if(!cRecipient.equals("[]")){
                String[] numbers = cRecipient.replaceAll("[\\[\\]\\s]", "").split(",");
                int[] result = Arrays.stream(numbers)
                        .mapToInt(Integer::parseInt)
                        .toArray();
                List<Long> receiverList = Arrays.stream(result)
                        .mapToObj(Long::valueOf)
                        .collect(Collectors.toList());
                noticeReq.setReceiverList(receiverList);
            }else{
                noticeReq.setReceiverList(new ArrayList<>());
            }
            noticeReq.setReviewer(userId);
            noticeReq.setExamine("1");
            noticeReq.setExReason("日程提醒，不需审核");
            noticeReq.setLinkId(oaSchedule.getNScheId());
            noticeReq.setLinkType("schedule");
            noticeService.addNotice(noticeReq,userId);
        }
    }

    @Override
    public void addSchedule(ScheduleReq scheduleReq, long l) {
        OaSchedule oaSchedule = new OaSchedule();
        oaSchedule.setCType(scheduleReq.getType());
        oaSchedule.setCState(scheduleReq.getState());
        oaSchedule.setCTitle(scheduleReq.getTitle());
        oaSchedule.setCDesc(scheduleReq.getDesc());
        LocalDateTime starttime = scheduleReq.getStarttime();
        oaSchedule.setDtStartTime(starttime.plusHours(8));
        LocalDateTime deadline = scheduleReq.getDeadline();
        oaSchedule.setDtDeadline(deadline.plusHours(8));
        oaSchedule.setNUserId(l);
        oaSchedule.setNDeptId(scheduleReq.getDeptname());
        oaSchedule.setCRecipient(scheduleReq.getReceiverList().toString());
        oaSchedule.setNBoardroomId(scheduleReq.getBoardroomId());

        //在会议室使用表中添加
        if(scheduleReq.getBoardroomId()!= 0){
            OaUseBoardroom oaUseBoardroom = new OaUseBoardroom();
//        oaUseBoardroom.setNBoardroomId();
            oaUseBoardroom.setNBoardroomId(scheduleReq.getBoardroomId());
            oaUseBoardroom.setDtStartTime(starttime.plusHours(8));
            oaUseBoardroom.setDtDeadline(deadline.plusHours(8));
            useBoardroomMapper.insert(oaUseBoardroom);
        }
        scheduleMapper.insert(oaSchedule);
    }

    @Override
    public int deleteScheduleById(Integer id) {
        return scheduleMapper.deleteScheduleById(id);
    }

    @Override
    public ScheduleResp getScheduleDetailById(Integer id) {
        QueryWrapper<OaSchedule> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("n_sche_id", id);
        OaSchedule oaSchedule = scheduleMapper.selectOne(queryWrapper);
        if(oaSchedule!= null){
            ScheduleResp build = ScheduleResp.builder()
                    .type(oaSchedule.getCType())
                    .starttime(oaSchedule.getDtStartTime())
                    .deadline(oaSchedule.getDtDeadline())
                    .title(oaSchedule.getCTitle())
                    .desc(oaSchedule.getCDesc())
                    .id(oaSchedule.getNScheId())
                    .build();
            if(oaSchedule.getNBoardroomId()!= 0){
                QueryWrapper<OaBoardroom> queryWrapper1 = new QueryWrapper<>();
                queryWrapper1.eq("n_boardroom_id", oaSchedule.getNBoardroomId());
                OaBoardroom oaBoardroom = boardroomMapper.selectOne(queryWrapper1);
                build.setBoardroom(oaBoardroom.getCNo());
            }
            if(oaSchedule.getCState().equals("1")){
                build.setState("紧急");
            }else if(oaSchedule.getCState().equals("2")){
                build.setState("重要");
            }else if(oaSchedule.getCState().equals("3")){
                build.setState("一般");
            }
            if(oaSchedule.getNUserId()!= 0){
                build.setPromoter(userMapper.selectUserById(oaSchedule.getNUserId()).getCRealName());
            }
            if(oaSchedule.getNDeptId()!= 0){
                build.setDeptname(deptMapper.selectDeptById(oaSchedule.getNDeptId()).getCDeptName());
            }
            String str = oaSchedule.getCRecipient();
            if(str!= null && !str.equals("[]")){
                String[] numbers = str.replaceAll("[\\[\\]\\s]", "").split(",");
                int[] result = Arrays.stream(numbers)
                        .mapToInt(Integer::parseInt)
                        .toArray();
                StringBuilder sb = new StringBuilder();
                for (int i:result
                     ) {
                    if(i!= 0&&userMapper.selectUserById(i)!= null){
                        sb.append(userMapper.selectUserById(i).getCRealName()).append(",");
                    }
                }
                build.setRecipient(sb.toString().substring(0,sb.length()-1));
            }else{
                build.setRecipient("所有人");
            }
            if(oaSchedule.getNBoardroomId()!= 0){
                build.setBoardroom(boardroomMapper.selectBoardroomById(oaSchedule.getNBoardroomId()).getCNo());
            }else{
                build.setBoardroom("无");
            }
            return build;
        }
        return null;
    }
}
